import React, { useEffect, useRef, useState } from 'react'
import { Form, Icon, Input } from 'antd'
import { useRequest } from 'ahooks'
import PropTypes from 'prop-types'
import Trigger from 'rc-trigger'
import 'rc-trigger/assets/index.css'
import { isEqual } from 'lodash'
import styles from './index.less'
import SlickTable from '@/components/SlickTable'
import request from '@/utils/request'
import { hasMoreThanOne } from '@/utils/utils'

function getTableData({ method, url }) {
  return request(url, {
    method,
  })
}

function getValue(selectedRows, dataSource, rowKey, label) {
  if (hasMoreThanOne(selectedRows)) {
    const selected = selectedRows[0]
    const data = dataSource.find(item => item[rowKey] === selected[rowKey])
    return (data || {})[label]
  }
  return undefined
}

function ComboGrid({
  form,
  onChange,
  value,
  url,
  method,
  action,
  placeholder,
  searchPlaceholder,
  columns,
  rowKey,
  label,
  tokenSeparators,
  extra,
  pick,
  disabled,
  params,
  onConfirm,
  filedName,
  style,
  search = true,
  searchableColumns = ['title', 'className', 'beanName'],
  getPopupContainer = trigger => trigger.parentNode,
  slickTableProps = {},
  ...restProps
}) {
  const [selectedRows, setSelectedRows] = useState(value)
  const [dataSource, setDataSource] = useState([])
  const [cachedDataSource, setCachedDataSource] = useState([])
  const [open, setOpen] = useState(false)
  const tableEl = useRef(null)
  // tableProps格式{dataSource,loading,onChange,pagination:{current,pageSize,total}}
  const { loading } = useRequest(() => getTableData({ url, method }), {
    onSuccess: (resultData) => {
      if (Array.isArray(resultData)) {
        setDataSource(resultData)
        setCachedDataSource(resultData)
      }
    },
  })

  function onPopupVisibleChange(isVisible) {
    if (!isVisible)
      onConfirm(selectedRows)

    setOpen(isVisible)
  }

  /**
   * 1、input元素被get包裹 会从props带入onChange方法,selectedRows 保证form取到的值是实时最新的
   * 2、只在更新阶段执行onChange，避免在初始化时触发rule校验（如果被getFieldDecorator包裹）
   */
  // useUpdateEffect(() => {
  //   if (isFunction(onChange)) {
  //     onChange(selectedRows);
  //   }
  // }, [selectedRows, onChange]);

  /**
   * 外部通过setFieldsValue设置值的时候，即时更新
   */
  useEffect(() => {
    if (Array.isArray(value)) {
      if (!isEqual(value, selectedRows)) {
        setSelectedRows(value)
        onChange(value)
      }
    }
  }, [value])

  return (
    <Trigger
      className={styles.combogrid}
      action={[action]}
      popupAlign={{
        overflow: {
          adjustX: true, // true 表示当下拉框宽度>所在容器宽度时 会自动切换 左右对齐
          adjustY: true, // true 表示当下拉框高度 > 所在容器高度是 会自动切换 上下对齐
        },
        offset: [0, 4],
      }}
      getPopupContainer={getPopupContainer}
      onPopupVisibleChange={isVisible => onPopupVisibleChange(isVisible)}
      mouseEnterDelay={0.3}
      builtinPlacements={{
        left: {
          points: ['cr', 'cl'],
        },
        right: {
          points: ['cl', 'cr'],
        },
        top: {
          points: ['bc', 'tc'],
        },
        bottom: {
          points: ['tc', 'bc'],
        },
        topLeft: {
          points: ['bl', 'tl'],
        },
        topRight: {
          points: ['br', 'tr'],
        },
        bottomRight: {
          points: ['tr', 'br'],
        },
        bottomLeft: {
          points: ['tl', 'bl'],
        },
      }}
      popupClassName={styles.combogridDropdown}
      popupVisible={open}
      popup={
        <div>
          {search && <Input.Search
            placeholder={searchPlaceholder}
            allowClear
            className={styles.search}
            onSearch={(value) => {
              setDataSource(
                cachedDataSource.filter((k) => {
                  return searchableColumns.some(col => k[col] && k[col].includes(value))
                }),
              )
            }}
          />}
          <SlickTable
            ref={tableEl}
            extra={extra}
            rowKey={rowKey}
            pick={pick}
            loading={loading}
            dataSource={dataSource}
            pagination={{ pageSize: 5 }}
            selectedRowKeys={selectedRows.map(row => row[rowKey])}
            onSelectRow={(selectedRows) => {
              const result = []
              selectedRows.map(val => result.push(val.orgName))
              setSelectedRows(selectedRows)
              onChange(selectedRows)
            }}
            columns={columns}
            {...slickTableProps}
          />
        </div>
      }
      {...restProps}
    >
      <Input
        style={style}
        placeholder={placeholder}
        disabled={disabled}
        // allowClear
        // onChange={e => {
        //   window.tableEl = tableEl;
        //   if (tableEl && tableEl.current) {
        //     tableEl.current.cleanSelectedKeys([], []);
        //   }
        // }}
        suffix={<Icon type="table" />}
        value={getValue(selectedRows, dataSource, rowKey, label)}
      />
    </Trigger>
  )
}

ComboGrid.defaultProps = {
  value: [],
  method: 'post',
  placeholder: '',
  searchPlaceholder: '',
  action: 'click',
  stretch: 'width',
  popupStyle: {},
  popupPlacement: 'bottomLeft',
  tokenSeparators: ',',
  destroyPopupOnHide: false,
  disabled: false,
  extra: null,
  pick: 'checkbox',
  params: {},
  onConfirm: () => {},
  filedName: 'filterVal',
}

ComboGrid.propTypes = {
  value: PropTypes.array,
  method: PropTypes.oneOf(['post', 'get']),
  url: PropTypes.string.isRequired,
  label: PropTypes.string.isRequired,
  rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired,
  columns: PropTypes.arrayOf(PropTypes.object).isRequired,
  placeholder: PropTypes.string,
  searchPlaceholder: PropTypes.string,
  tokenSeparators: PropTypes.string,
  action: PropTypes.oneOf(['hover', 'click']),
  popupStyle: PropTypes.object,
  stretch: PropTypes.oneOf(['width', 'height', 'minWidth', 'minHeight']),
  popupPlacement: PropTypes.oneOf([
    'top',
    'right',
    'bottom',
    'right',
    'topLeft',
    'topRight',
    'bottomLeft',
    'bottomRight',
  ]),
  destroyPopupOnHide: PropTypes.bool,
  disabled: PropTypes.bool,
  params: PropTypes.object,
  extra: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
  pick: PropTypes.oneOf(['checkbox', 'radio']),
  onConfirm: PropTypes.func,
  filedName: PropTypes.string,
}

export default Form.create()(ComboGrid)
